package com.zy.dcs.appender;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.classic.spi.ThrowableProxy;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import com.mysql.cj.util.StringUtils;
import com.zy.dcs.utils.IpUtils;
import com.zy.dcs.utils.JdbcUtils;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.*;

public class MySqlAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {

    public String applyName;

    public String applyPort;

    public String url;

    public String username;

    public String password;

    public String tableName;



    @Override
    protected void append(ILoggingEvent eventObject) {
        String driver = "com.mysql.cj.jdbc.Driver";

        String levelStr = eventObject.getLevel().levelStr;

        String localServerIp = IpUtils.getHostIp();

        if(!StringUtils.isNullOrEmpty(applyPort)){
            localServerIp = localServerIp+":"+applyPort;
        }

        JdbcUtils jdbcUtils = new JdbcUtils( driver,  url,  username,  password);
        String sql = "insert into "+tableName+"(apply_name,resume,detail,level,local_server_ip,collection_time) values(?,?,?,?,?,?)";

        Map<String,String> map = new HashMap<>();
        getException(eventObject,map);
        List params = new ArrayList<>();
        params.add(applyName);
        params.add(map.get("resume"));
        params.add(map.get("detail"));
        params.add(levelStr);
        params.add(localServerIp);
        params.add(new Date());
        try {
            jdbcUtils.updateByParams(sql,params);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private Map<String,String> getException(ILoggingEvent event,Map<String,String> map){
        IThrowableProxy iThrowableProxy = event.getThrowableProxy();
        StringBuilder sb = new StringBuilder();

        // 打印堆栈信息
        if (iThrowableProxy instanceof ThrowableProxy) {
            ThrowableProxy throwableProxy = (ThrowableProxy) iThrowableProxy;
            Throwable throwable = throwableProxy.getThrowable();
            String throwableMsg = throwable.getMessage();
            StackTraceElementProxy[] stackTraceElementProxy = iThrowableProxy.getStackTraceElementProxyArray();

            sb.append("<font color=#FF0000>"+event.getFormattedMessage()+"</font>").append("</br>");
            if (throwableMsg.trim().length()>0) {
                sb.append("<font color=#FF0000>"+throwableMsg+"</font>").append("</br>");
            }
            for (StackTraceElementProxy proxy : stackTraceElementProxy) {
                 sb.append(proxy.getSTEAsString()).append("</br>");
            }
        } else {
            sb.append(event.getMessage());
        }
        map.put("resume",event.getFormattedMessage());
        map.put("detail",sb.toString());
        return map;
    }

    public String getLocalServerIp() {
        try {
            InetAddress inetAddress = InetAddress.getLocalHost();
            String localServerIp = inetAddress.getHostAddress();
            return localServerIp;
        } catch (UnknownHostException e) {
            return "500";
        }
    }

    public String getApplyName() {
        return applyName;
    }

    public void setApplyName(String applyName) {
        this.applyName = applyName;
    }

    public String getApplyPort() {
        return applyPort;
    }

    public void setApplyPort(String applyPort) {
        this.applyPort = applyPort;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }
}
